/*!
\copyright  Copyright (c) 2020-2021 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file
\defgroup   leabm LE Audio Broadcast Manager
\ingroup    bt_domain
\brief      Manager for LE Broadcast Audio.
*/

#ifndef LE_BROADCAST_MANAGER_H_
#define LE_BROADCAST_MANAGER_H_

#include <device.h>

#include "audio_sources_list.h"
#include "scan_delegator_role.h"
#include "domain_message.h"

#define BASIC_AUDIO_ANNOUNCEMENT_SERVICE_UUID       0x1851
#define BROADCAST_AUDIO_ANNOUNCEMENT_SERVICE_UUID   0x1852

/*\{*/

typedef enum le_broadcast_manager_messages
{
    LE_BROADCAST_MANAGER_STOP_CFM = LE_BROADCAST_MANAGER_MESSAGE_BASE,
    LE_BROADCAST_MANAGER_REMOVE_ALL_SOURCES_CFM,
    LE_BROADCAST_MANAGER_MESSAGE_END
} le_broadcast_manager_messages_t;

#if defined(INCLUDE_LE_AUDIO_BROADCAST)

/*! \brief Initialises the LE Broadcast Manager

    Initialises the LE Broadcast manager, which initialises all components required for Broadcast LE Audio
 */
bool LeBroadcastManager_Init(Task init_task);

/*! \brief Stop the LE broadcast manager receiving a broadcast.
    \param requestor The task requesting the disconnection. May be set to NULL
    if the requestor does not require a response message.

    A LE_BROADCAST_MANAGER_STOP_CFM message is sent when all broadcast streams
    disconnected and the manager is stopped. The message is sent to the requestor
    even if the manager was already stopped when the function was called.

    If LeBroadcastManager_Stop is called by multiple requestors, each will
    receive a LE_BROADCAST_MANAGER_STOP_CFM.

    \note This function guarantees to send a LE_BROADCAST_MANAGER_STOP_CFM if
    the broadcast assistant is not connected. If the broadcast assistant is
    connected, it may interfere with the stopping procedure. For example, the
    assistant may request that the broadcast manager re-syncs to a BIS. This is
    not currently handled and the manager may not respond in such cases. To
    guarantee receiving the LE_BROADCAST_MANAGER_STOP_CFM ensure the broadcast
    assistant is disconnected prior to calling this function.
*/
void LeBroadcastManager_Stop(Task requestor);

/*! \brief Pause the LE broadcast manager.
    \param requestor The task requesting the pause. Must be set to a valid task.

    Pausing means the LE broadcast manager will stop sync to all BISes. But it
    will remain synchronised to periodic advertisements.

    When paused, LE broadcast manager will ignore any requests from a broadcast
    assistant to synchronise to a BIS. It will comply with requests to sync or
    unsync to the periodic advertisement train.
*/
void LeBroadcastManager_Pause(Task requestor);

/*! \brief Mute using syncronised start mute.
    \param seconds Number of seconds to mute for.

    If seconds is set to 0 the output will be un-muted
*/
void LeBroadcastManager_OutOfEarMute(uint8 seconds);

/*! \brief Unsync from the broadcast source.
*/
void LeBroadcastManager_Unsync(void);

/*! \brief Resume the LE broadcast manager.
    \param requestor The task requesting the resume. Must be set to a valid task.

    The LE broadcast manager will only resume when all tasks requesting pause
    have called this function.

    The LE broadcast manager will resume sync to a BIS the broadcast
    assistant has requested.
*/
void LeBroadcastManager_Resume(Task requestor);

/*! \brief Query if the LE broadcast manager is paused.
    \return TRUE if paused.
*/
bool LeBroadcastManager_IsPaused(void);

/*! \brief Query if the device is currently receiving a broadcast.
    \return TRUE if broadcast receive is active.
*/
bool LeBroadcastManager_IsBroadcastReceiveActive(void);

/*! \brief Check if any broadcast source is currently pa synced

    Check all possible broadcast sources and check if any are synced to a
    periodic advertisement.

    \return TRUE if at least one source is pa synced; FALSE otherwise.
*/
bool LeBroadcastManager_IsAnySourceSyncedToPa(void);

/*! \brief Check if any broadcast source is currently synced to a BIS

    Check all possible broadcast sources and check if any are synced to a
    BIS.

    \return TRUE if at least one source is BIS synced; FALSE otherwise.
*/
bool LeBroadcastManager_IsAnySourceSyncedToBis(void);


/*! \brief Get the device for the routed broadcast source.

    This function will only try to get the device for the broadcast source
    based on its address. It will not try to get the device of the broadcast
    assistant, even if there is one connected.

    \param source Audio source to get the device for.

    \return A valid device_t or NULL if no device for the broadcast source
            address could be found.
*/
device_t LeBroadcastManager_GetDeviceForAudioSource(audio_source_t source);

/*! \brief Find out if we have an active broadcast source which is from 
           the broadcast assistant (colocated)

    \note Use the function LeBroadcastSource_IsActiveSourceNonColocated
        to check for non co-located broadcasts. If this functio returns 
        FALSE, it does not mean that there is a non-colocated broadcast source

    \return TRUE if a co-located broadcast source was found.
*/
bool LeBroadcastSource_IsActiveSourceColocated(void);

/*! \brief Find out if we have an active broadcast source which is \b not 
           from the broadcast assistant (non-colocated)

    \note Use the function LeBroadcastSource_IsActiveSourceColocated
        to check for co-located broadcasts. A return value of FALSE
        does not mean that there is a colocated broadcast source

    \return TRUE if a non co-located broadcast source was found
*/
bool LeBroadcastSource_IsActiveSourceNonColocated(void);

/*! \brief Find the ISO interval of the current broadcast source

    Find the interval of packets for a broadcast source. 

    \return The packet interval in units of 1.25 ms. 0 if no active broadcast source.
*/
uint16 LeBroadcastSource_GetActiveSourceIsoInterval(void);

/*! \brief Remove all Broadcast Sources from the manager and the BASS server.

    Unsync from any active Broadcast Source and then reset the state of all
    Broadcast Sources in le_broadcast_manager and the GATT BASS server.

    \param requestor The task requesting to remove all sources. May be set to NULL
                     if the requestor does not require a response message.
*/
void LeBroadcastManager_RemoveAllSources(Task Requestor);

/*! \brief Add a boadcast source to the local BASS server.

    This function can be used to make add a broadcast source locally, without
    having to be connected to a Broadcast Assistant.

    Once added the source will use the self-scan procedure to scan for the
    periodic adverts from the broadcast source.

    Most of the parameters of the broadcast source will use preset values but
    the broadcast_id must be given as this is how the broadcast source is
    identified dudring the self-scan process.

    The broadcast source will be added to the local BASS server using the same
    'Add Source' procedure that a Broadcast Assistant device would use.

    \param adv_sid The Advertising Set ID of the broadcast source.
    \param broadcast_id The broadcast_id of the broadcast source.
*/
void LeBroadcastManager_LocallyAddBroadcastSource(uint8 adv_sid, uint32 broadcast_id);

#else /* INCLUDE_LE_AUDIO_BROADCAST */

#define LeBroadcastManager_IsBroadcastReceiveActive() FALSE

#define LeBroadcastManager_Stop(requestor) MessageSend((requestor), LE_BROADCAST_MANAGER_STOP_CFM, NULL)

#define LeBroadcastManager_IsAnySourceSyncedToPa() FALSE

#define LeBroadcastManager_IsAnySourceSyncedToBis() FALSE

#define LeBroadcastManager_Pause(requestor)

#define LeBroadcastManager_Resume(requestor)

#define LeBroadcastManager_GetDeviceForAudioSource(source) ((device_t)NULL); UNUSED(source)

#define LeBroadcastManager_IsPaused() FALSE

#define LeBroadcastManager_Unsync()

#define LeBroadcastManager_RemoveAllSources(task)   UNUSED(task)

#define LeBroadcastManager_LocallyAddBroadcastSource(adv_sid, broadcast_id) UNUSED(adv_sid); UNUSED(broadcast_id)

#endif /* INCLUDE_LE_AUDIO_BROADCAST */

/*\}*/

#endif /* LE_BROADCAST_MANAGER_H_ */
